﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using WMSSoft.Lib.WinKStart;
using WMSSoft.Lib.Basic;
using WMSSoft.Lib.Const;
using WMSSoft.Lib.Enums;
using WMSSoft.WinKStart.Lib;
using System.Windows.Interop;
using WMSSoft.Lib.WinKStart.Model.MenuConfig;

namespace WMSSoft.WinKStart
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        #region Members        
        //private int _ActiveTabIndex = -1;
        IntPtr m_CurrentGUIHandle = IntPtr.Zero;
        
        private Dictionary<int, cStartmenuItem> _CurrentVisibleSystemItems = null;
        private Dictionary<int, cStartmenuItem> _CurrentVisibleShutdownItems = null;
        private Dictionary<int, string> m_RegionsToUpdate = null;
        private static ManualResetEvent _objThreadSync = new ManualResetEvent(false);   // Object to Thread sync

        private RegionRenderer _TabPageRenderer = null;
        //private StartmenuSearch m_MenuSearch = null;
        private System.Windows.Threading.DispatcherTimer m_UpdatedGUIElements = null;
        private System.Windows.Threading.DispatcherTimer m_WebSearchResultUpdate = null;
        private System.Windows.Threading.DispatcherTimer m_GUI_Heartbeat = null;

        private string m_APPLICATION_CONFIG_SUBPATH = @"WMSSoft\WinKStart\Conf";
        string _LOG_SUBPATH = @"WMSSoft\WinKStart\Log";
        private string m_USERCONFIG_FILENAME = "userconfig.xml";
        const string START_MENU_BUTTON_PROCESS_FILENAME = "WinKStartBtn.exe";

        private bool m_UpdatedDataSourceRunning = false;
        int _iCloseRaiseCounter = 0;

        #endregion

        #region Initialise
        public MainWindow()
        {
            CMessagelogging.LoggingFilePath = @"WMSSoft\WinKStart\Log";
            InitializeComponent();
            try
            {
                CMessagelogging.AppendMessage("Start Initializing WinKStart", EMessageTypes.Information);
                m_RegionsToUpdate = new Dictionary<int, string>();
                //Create a timer instance to update search result list
                //System.Diagnostics.Stopwatch odiagnosticsTime = new System.Diagnostics.Stopwatch();
                m_WebSearchResultUpdate = new System.Windows.Threading.DispatcherTimer(System.Windows.Threading.DispatcherPriority.Send);
                m_WebSearchResultUpdate.IsEnabled = false;
                m_WebSearchResultUpdate.Tick += new EventHandler(m_WebSearchResultUpdate_Tick);
                m_WebSearchResultUpdate.Interval = new TimeSpan(0, 0, 0, 0, 500);

                m_UpdatedGUIElements = new System.Windows.Threading.DispatcherTimer(System.Windows.Threading.DispatcherPriority.Send);
                m_UpdatedGUIElements.IsEnabled = false;
                m_UpdatedGUIElements.Tick += m_UpdatedGUIElements_Tick;
                m_UpdatedGUIElements.Interval = new TimeSpan(0, 0, 0, 0, 500);

                m_GUI_Heartbeat = new System.Windows.Threading.DispatcherTimer(System.Windows.Threading.DispatcherPriority.Send);
                m_GUI_Heartbeat.IsEnabled = false;
                m_GUI_Heartbeat.Tick += GUI_HeartBeat;
                m_GUI_Heartbeat.Interval = new TimeSpan(0, 0, 1);

                //Create user settings path
                string sUserSettingsPath = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData),
                                                                  m_APPLICATION_CONFIG_SUBPATH);
                //load usersettings
                CMessagelogging.AppendMessage("Load Usersettings", EMessageTypes.Information);
                WMSSoft.Lib.WinKStart.cUserSettingsReader.LoadSettings(System.IO.Path.Combine(sUserSettingsPath, m_USERCONFIG_FILENAME));
                
                string sConfigPath = System.IO.Path.Combine(cUserSettingsReader.ConfigPath, @"content.xml");

                //load languagefiles
                CMessagelogging.AppendMessage("Load Language Files", EMessageTypes.Information);
                cLanguageLoader.Load();
                cLanguageLoader.SetLanguage(System.Globalization.CultureInfo.CurrentCulture.TextInfo.CultureName);

                CMessagelogging.AppendMessage("Load WinKStart - StartButton", EMessageTypes.Information);
                //Load StartButton - Process
                LoadStartButton();


                if (System.IO.File.Exists(sConfigPath) == false) throw new Exception("Startmenu configuration File not found!");

                //odiagnosticsTime.Restart();
                //_ConfigMenuReader = new cMenuConfigReader();
                CMessagelogging.AppendMessage("Load WinKStart - Content-Configuration", EMessageTypes.Information);
                cMenuConfigReader.UpdatedDataSource += _ConfigMenuReader_UpdatedDataSource;
                cMenuConfigReader.LoadMenuConfig(sConfigPath);
                InitGUIElementsForEvents();

                _CurrentVisibleShutdownItems = new Dictionary<int, cStartmenuItem>();
                _CurrentVisibleSystemItems = new Dictionary<int, cStartmenuItem>();
                //Applay Window Style
                cStyleChanger.ApplyStyleToWindow(this);
                cStyleChanger.ApplyStyleToImage(img_UserPicture, StyleElements.STYLE_ELEMENT__PICTURE_USER_PICTURE);
                cStyleChanger.ApplyStyleToElements(lbl_UserName, StyleElements.STYLE_ELEMENT__ELEMENT_USER_COMPUTER_NAME);
                cStyleChanger.ApplyStyleToImage(img_SearchPicture, StyleElements.STYLE_ELEMENT__PICTURE_SEARCH_PICTURE);
                cStyleChanger.ApplyStyleToElements(lbl_Search, StyleElements.STYLE_ELEMENT__ELEMENT_SEARCH);
                cStyleChanger.ApplyStyleToElements(txt_ProgramSearchbox, StyleElements.STYLE_ELEMENT__ELEMENT_SEARCHBOX);
                cStyleChanger.ApplyStyleToRegionPosition(pan_RegionWrapper);
                cStyleChanger.ApplyStyleToRegionButtons(pan_ButtonsHost);
                pan_Buttons.Margin = new Thickness(0,-80,0,0);
                cStyleChanger.ApplyStyleToImage(img_selector, StyleElements.STYLE_ELEMENT__PICTURE_SELECTOR_PICTURE);
                cStyleChanger.ApplyStyleToImage(img_SelectNextButtons, StyleElements.STYLE_ELEMENT__PICTURE_SELECT_NEXT_PICTURE);
                cStyleChanger.ApplyStyleToImage(img_SelectPreviousButtons, StyleElements.STYLE_ELEMENT__PICTURE_SELECT_PREVIOUS_PICTURE);
                //Render all Tabpages on Startmenu
                _TabPageRenderer = new RegionRenderer(img_selector, img_SelectPreviousButtons, img_SelectNextButtons);

                if (_TabPageRenderer != null)
                {
                    _TabPageRenderer.RenderTabpages(pan_RegionWrapper, pan_Buttons, this);
                    _TabPageRenderer.SelectionChanged += _TabPageRenderer_SelectionChanged;
                }
 
                //Set Text for logged in user and computer name
                lbl_UserName.Content = WMSSoft.Lib.Basic.LanguageStrings.GetText("##USERNAME## on ##COMPUTER##")
                                                   .Replace("##USERNAME##", Environment.UserName)
                                                   .Replace("##COMPUTER##", Environment.MachineName);
                lbl_Search.Content = WMSSoft.Lib.Basic.LanguageStrings.GetText("Search");


                m_UpdatedGUIElements.IsEnabled = true;
                CMessagelogging.AppendMessage("Load WinKStart - Event-Handler-Configuration", EMessageTypes.Information);
                //Init all EventHandlers
                InitAllEventHandlers();
                CMessagelogging.AppendMessage("WinKStart - Initialization done", EMessageTypes.Information);
            }
            catch (Exception ex)
            {
                CMessagelogging.AppendMessage("An Error was occured on initialize and load " + BasicConsts.WINKSTART_APPLICATION_NAME + "!", ex, true, EMessageTypes.Error);
                Close();
            }
        }

        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);
            HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
            source.AddHook(WndProc);
        }

        IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            //this is the wpf equivalent to WinForms WNDProd
            if (msg == WMSSoft.Lib.Shell.ShellAPI.WM_ACTION_WINKSTART_SHOW)
            {
                this.Visibility = System.Windows.Visibility.Visible;
            }
            else if (msg == WMSSoft.Lib.Shell.ShellAPI.WM_ACTION_WINKSTART_HIDE)
            {
                this.Visibility = System.Windows.Visibility.Hidden;
            }
            else if (msg == WMSSoft.Lib.Shell.ShellAPI.WM_ACTION_WINKSTART_CLOSE)
            {
                Execute_Procedure(eExecutionProcedure.winkstart_close);
            }
            else if (msg == WMSSoft.Lib.Shell.ShellAPI.WM_ACTION_OPENSETTINGSDLG)
            {
                Execute_Procedure(eExecutionProcedure.winkstart_settings);
            }
            else if (msg == WMSSoft.Lib.Shell.ShellAPI.WM_ACTION_BTN_ASK_GUI_LIVES)
            {
                WMSSoft.Lib.Shell.ShellAPI.SendMessage(GetStartButtonManagementHandle(), WMSSoft.Lib.Shell.ShellAPI.WM_ACTION_BTN_ASK_GUI_LIVES, IntPtr.Zero, m_CurrentGUIHandle);
            }
            return IntPtr.Zero;
        }

        IntPtr GetStartButtonManagementHandle()
        {
            IntPtr handleWinKStartManagement = WMSSoft.Lib.Shell.ShellAPI.FindWindowEx(IntPtr.Zero, IntPtr.Zero, "WinKStart.CWinKStartManagement", null);
            return handleWinKStartManagement;
        }

        void TellCurrentHandle()
        {
            if (m_CurrentGUIHandle == IntPtr.Zero)
            {
                HwndSource source = (HwndSource)HwndSource.FromVisual(this);
                if (source != null)
                    source.AddHook(HandleMsg);

                CMessagelogging.AppendMessage("Tell WinKStart - StartButton GUI's handle", EMessageTypes.Information);
                m_CurrentGUIHandle = new WindowInteropHelper(Application.Current.MainWindow).Handle;
            }

            WMSSoft.Lib.Shell.ShellAPI.SendMessage(GetStartButtonManagementHandle(), WMSSoft.Lib.Shell.ShellAPI.WM_ACTION_SET_CALLER, IntPtr.Zero, m_CurrentGUIHandle);
        } 

        void CloseStartButton()
        {
            CMessagelogging.AppendMessage("Shutdown WinKStart - StartButton", EMessageTypes.Information);
            WMSSoft.Lib.Shell.ShellAPI.SendMessage(GetStartButtonManagementHandle(), WMSSoft.Lib.Shell.ShellAPI.WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
        }

        private void LoadStartButton()
        {
            try
            {
                string sStartMenuButtonProcessFilename = System.IO.Path.Combine(cUserSettingsReader.ApplicationPath, START_MENU_BUTTON_PROCESS_FILENAME);
                if (System.IO.File.Exists(sStartMenuButtonProcessFilename) == false) throw new Exception("Invalid WinKStart installation! Please reinstall it.");
                //Create StartButton Parameters
                WMSSoft.Lib.Shell.ShellAPI.ShellExecute(0, "open", sStartMenuButtonProcessFilename, GetStartMenuProzessArgument(), "", 5);

            }
            catch (Exception Ex)
            {
                throw new Exception("Error on loading StartMenu - Caller!", Ex);
            }
        }

        string GetStartMenuProzessArgument()
        {
            try
            {
                if (cUserSettingsReader.WinKStart != null)
                {
                    string sLogPath = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData),
                                                             _LOG_SUBPATH);
                    string sResult = Convert.ToString(cUserSettingsReader.WinKStart.Behavior.ButtonMouseOpen) + " " +
                                     Convert.ToString(cUserSettingsReader.WinKStart.Behavior.ButtonKeyboardOen) + " " +
                                     Convert.ToString(cUserSettingsReader.WinKStart.Behavior.ShiftButtonMouseOpen) + " " +
                                     Convert.ToString(cUserSettingsReader.WinKStart.Behavior.ShiftButtonKeyboardOpen) + " " +
                                     Convert.ToString(cUserSettingsReader.WinKStart.Behavior.MoveButtonMouseOpen) + " " +
                                     Convert.ToString(cUserSettingsReader.WinKStart.Behavior.MoveButtonMouseOpenDelayTime) + " " +
                                     " \" \" " + //cUserSettingsReader.StartButtonSettings.StartButtonSymbol + " " +
                                     Convert.ToString(cUserSettingsReader.WinKStart.StartButton.DisableMetroScreen) + " " +
                                     Convert.ToString(cUserSettingsReader.WinKStart.StartButton.DisableHotEdges) + " " +
                                     Convert.ToString(cUserSettingsReader.WinKStart.StartButton.RestoreAfterFailedGUI) + " " +
                                     GetContextMenuOptionsValue() + " " +
                                     " 7 " + 
                                     Convert.ToString(cUserSettingsReader.WinKStart.StartButton.ReplaceStartButton) + " " +
                                     Convert.ToString(cUserSettingsReader.WinKStart.StartButton.ReplaceAllTaskbars) + " " +
                                     cUserSettingsReader.LanguagesPath + " " +
                                     sLogPath + @"\";
                                     //System.IO.Path.Combine(cUserSettingsReader.ApplicationPath, cUserSettingsReader.LanguagesPath);
                    return sResult;
                }
                else return "";
            }
            catch
            {
                return "";
                //Messagelogging.AppendMessage("Unable to update GUI!!", Ex, false, EMessageTypes.Error);
            }
        }

        string GetContextMenuOptionsValue()
        {
            try
            {
                int itmpContextMenuOptions = 0;
                //Context-Menu enabled value Bit 0
                if (cUserSettingsReader.WinKStart.ContextMenu.Enabled) itmpContextMenuOptions += 1;
                //MenuItem Explorer Bit 1
                if (cUserSettingsReader.WinKStart.ContextMenu.Explorer) itmpContextMenuOptions += 2;
                //MenuItem Cmd Shell Bit 2
                if (cUserSettingsReader.WinKStart.ContextMenu.CmdShell) itmpContextMenuOptions += 4;
                //MenuItem PowerShell Bit 3
                if (cUserSettingsReader.WinKStart.ContextMenu.PowerShell) itmpContextMenuOptions += 8;
                //MenuItem WinKStartSettings Bit 4
                if (cUserSettingsReader.WinKStart.ContextMenu.WinKStartSettings) itmpContextMenuOptions += 16;
                //MenuItem WinKStart Exit Bit 5
                if (cUserSettingsReader.WinKStart.ContextMenu.WinKStartExit) itmpContextMenuOptions += 32;
                //MenuItem Run Bit 6
                if (cUserSettingsReader.WinKStart.ContextMenu.Run) itmpContextMenuOptions += 64;
                //MenuItem Taskmanager Bit 7
                if (cUserSettingsReader.WinKStart.ContextMenu.Taskmanager) itmpContextMenuOptions += 128;
                //MenuItem Suchen Bit 8
                if (cUserSettingsReader.WinKStart.ContextMenu.Search) itmpContextMenuOptions += 256;
                //MenuItem System Bit 9
                if (cUserSettingsReader.WinKStart.ContextMenu.System) itmpContextMenuOptions += 512;
                //MenuItem ProgramsAndFeatures Bit 10
                if (cUserSettingsReader.WinKStart.ContextMenu.ProgramsAndFeatures) itmpContextMenuOptions += 1024;
                //MenuItem SystemControl Bit 11
                if (cUserSettingsReader.WinKStart.ContextMenu.Systemcontrol) itmpContextMenuOptions += 2048;
                //MenuItem CmdShell(Administrator) Bit 12
                if (cUserSettingsReader.WinKStart.ContextMenu.CmdShellAdministrator) itmpContextMenuOptions += 4096;
                //MenuItem PowerShell(Adminisstrator) Bit 13
                if (cUserSettingsReader.WinKStart.ContextMenu.PowerShellAdministrator) itmpContextMenuOptions += 8192;
                //MenuItem MobilityCenter Bit 14
                if (cUserSettingsReader.WinKStart.ContextMenu.MobiltyCenter) itmpContextMenuOptions += 16384;
                //MenuItem PowerOptions Bit 15
                if (cUserSettingsReader.WinKStart.ContextMenu.PowerOptions) itmpContextMenuOptions += 32768;
                //MenuItem EventViewer Bit 16
                if (cUserSettingsReader.WinKStart.ContextMenu.EventViewer) itmpContextMenuOptions += 65536;
                //MenuItem Bit 17
                if (cUserSettingsReader.WinKStart.ContextMenu.Enabled) itmpContextMenuOptions += 131072;
                //MenuItem Networkconnections Bit 18
                if (cUserSettingsReader.WinKStart.ContextMenu.NetworkConnections) itmpContextMenuOptions += 262144;
                //MenuItem Diskmanagement Bit 19
                if (cUserSettingsReader.WinKStart.ContextMenu.Diskmanagement) itmpContextMenuOptions += 524288;
                //MenuItem Computermanagement Bit 20
                if (cUserSettingsReader.WinKStart.ContextMenu.Computermanagement) itmpContextMenuOptions += 1048576;
                //MenuItem Session Control
                if (cUserSettingsReader.WinKStart.ContextMenu.WindowsSessionCtl) itmpContextMenuOptions += 2097152;

                return Convert.ToString(itmpContextMenuOptions);
            }
            catch (Exception Ex)
            {
                throw new Exception("Unable to set Context Menu Options!", Ex);
            }
        }

        #region "Event Handling used in content.xml
        private void InitAllEventHandlers()
        {
            try
            {                
                //MouseUp Event
                img_UserPicture.MouseUp += RaiseEvent_MouseUp;
                img_UserPicture.PreviewMouseUp += RaiseEvent_MouseUp;
                lbl_UserName.MouseUp += RaiseEvent_MouseUp;
                lbl_UserName.PreviewMouseUp += RaiseEvent_MouseUp;
                lbl_AppName.MouseUp += RaiseEvent_MouseUp;
                lbl_AppName.PreviewMouseUp += RaiseEvent_MouseUp;
                img_SearchPicture.MouseUp += RaiseEvent_MouseUp;
                img_SearchPicture.PreviewMouseUp += RaiseEvent_MouseUp;
                lbl_Search.MouseUp += RaiseEvent_MouseUp;
                lbl_Search.PreviewMouseUp += RaiseEvent_MouseUp;
                txt_ProgramSearchbox.MouseUp += RaiseEvent_MouseUp;
                txt_ProgramSearchbox.PreviewMouseUp += RaiseEvent_MouseUp;
                //MouseEnter Event
                img_UserPicture.MouseEnter += RaiseEvent_MouseEnter;
                lbl_UserName.MouseEnter += RaiseEvent_MouseEnter;
                lbl_AppName.MouseEnter += RaiseEvent_MouseEnter;
                img_SearchPicture.MouseEnter += RaiseEvent_MouseEnter;
                lbl_Search.MouseEnter += RaiseEvent_MouseEnter;
                txt_ProgramSearchbox.MouseEnter += RaiseEvent_MouseEnter;
                //MouseLeave Event
                img_UserPicture.MouseLeave += RaiseEvent_MouseLeave;
                lbl_UserName.MouseLeave += RaiseEvent_MouseLeave;
                lbl_AppName.MouseLeave += RaiseEvent_MouseLeave;
                img_SearchPicture.MouseLeave += RaiseEvent_MouseLeave;
                lbl_Search.MouseLeave += RaiseEvent_MouseLeave;
                txt_ProgramSearchbox.MouseLeave += RaiseEvent_MouseLeave;
                ////KeyDown Event
                //img_UserPicture.KeyDown += RaiseEvent_KeyDown;
                //img_UserPicture.PreviewKeyDown += RaiseEvent_KeyDown;
                //lbl_UserName.KeyDown += RaiseEvent_KeyDown;
                //lbl_UserName.PreviewKeyDown += RaiseEvent_KeyDown;
                //lbl_AppName.KeyDown += RaiseEvent_KeyDown;
                //lbl_AppName.PreviewKeyDown += RaiseEvent_KeyDown;
                //img_SearchPicture.KeyDown += RaiseEvent_KeyDown;
                //img_SearchPicture.PreviewKeyDown += RaiseEvent_KeyDown;
                //lbl_Search.KeyDown += RaiseEvent_KeyDown;
                //lbl_Search.PreviewKeyDown += RaiseEvent_KeyDown;
                //txt_ProgramSearchbox.KeyDown += RaiseEvent_KeyDown;
                //txt_ProgramSearchbox.PreviewKeyDown += RaiseEvent_KeyDown;
                //KeyUp Event
                img_UserPicture.KeyUp += RaiseEvent_KeyUp;
                img_UserPicture.PreviewKeyUp += RaiseEvent_KeyUp;
                lbl_UserName.KeyUp += RaiseEvent_KeyUp;
                lbl_UserName.PreviewKeyUp += RaiseEvent_KeyUp;
                lbl_AppName.KeyUp += RaiseEvent_KeyUp;
                lbl_AppName.PreviewKeyUp += RaiseEvent_KeyUp;
                img_SearchPicture.KeyUp += RaiseEvent_KeyUp;
                img_SearchPicture.PreviewKeyUp += RaiseEvent_KeyUp;
                lbl_Search.KeyUp += RaiseEvent_KeyUp;
                lbl_Search.PreviewKeyUp += RaiseEvent_KeyUp;
                txt_ProgramSearchbox.KeyUp += RaiseEvent_KeyUp;
                txt_ProgramSearchbox.PreviewKeyUp += RaiseEvent_KeyUp;
                //GotFocus Event
                img_UserPicture.GotFocus += RaiseEvent_GotFocus;
                lbl_UserName.GotFocus += RaiseEvent_GotFocus;
                lbl_AppName.GotFocus += RaiseEvent_GotFocus;
                img_SearchPicture.GotFocus += RaiseEvent_GotFocus;
                lbl_Search.GotFocus += RaiseEvent_GotFocus;
                txt_ProgramSearchbox.GotFocus += RaiseEvent_GotFocus;             
                //LeaveFocus Event
                img_UserPicture.LostFocus += RaiseEvent_LostFocus;
                lbl_UserName.LostFocus += RaiseEvent_LostFocus;
                lbl_AppName.LostFocus += RaiseEvent_LostFocus;
                img_SearchPicture.LostFocus += RaiseEvent_LostFocus;
                lbl_Search.LostFocus += RaiseEvent_LostFocus;
                txt_ProgramSearchbox.LostFocus += RaiseEvent_LostFocus;  
                //SelectionChange Event

                //TextChanged Event
                txt_ProgramSearchbox.TextChanged += RaiseEvent_TextChanged;
            }
            catch (Exception ex)
            {
                CMessagelogging.AppendMessage("Error while init all Events!", ex, true, EMessageTypes.Error);
            }
        }

        void RaiseEvent_TextChanged(object sender, TextChangedEventArgs e)
        {
            ProcessEvent(((FrameworkElement)sender).Name, "TextChanged", null);
        }

        void RaiseEvent_LostFocus(object sender, RoutedEventArgs e)
        {
            ProcessEvent(((FrameworkElement)sender).Name, "LostFocus", null);
        }

        void RaiseEvent_GotFocus(object sender, RoutedEventArgs e)
        {
            ProcessEvent(((FrameworkElement)sender).Name, "GotFocus", null);
        }

        void RaiseEvent_KeyUp(object sender, KeyEventArgs e)
        {
            ProcessEvent(((FrameworkElement)sender).Name, "KeyUp", e.KeyStates);
        }

        void RaiseEvent_KeyDown(object sender, KeyEventArgs e)
        {
            ProcessEvent(((FrameworkElement)sender).Name, "KeyDown", null);
        }

        void RaiseEvent_MouseLeave(object sender, MouseEventArgs e)
        {
            ProcessEvent(((FrameworkElement)sender).Name, "MouseLeave", null);
        }

        void RaiseEvent_MouseEnter(object sender, MouseEventArgs e)
        {
            ProcessEvent(((FrameworkElement)sender).Name, "MouseEnter", null);
        }

        void RaiseEvent_MouseUp(object sender, MouseButtonEventArgs e)
        {
            ProcessEvent(((FrameworkElement)sender).Name, "MouseUp", null);
        }

        void RaiseEvent_MouseMove(object sender, MouseEventArgs e)
        {
            ProcessEvent(((FrameworkElement)sender).Name, "MouseMove", null);
        }

        void RaiseEvent_MouseDown(object sender, MouseButtonEventArgs e)
        {
            ProcessEvent(((FrameworkElement)sender).Name, "MouseDown", null);
        }
#endregion

        void m_UpdatedGUIElements_Tick(object sender, EventArgs e)
        {
            try
            {
                Dictionary<int, string>.KeyCollection tmpRegionKeys = m_RegionsToUpdate.Keys;
                if (tmpRegionKeys != null && tmpRegionKeys.Count > 0)
                {
                    //if (_ConfigMenuReader.DataSources.IsDataSourceUpdated(e.Name) == true)
                    {
                        int iKeyItem = tmpRegionKeys.First();
                        if (cMenuConfigReader.DataSourcesToRegion.ContainsKey(m_RegionsToUpdate[iKeyItem]) == true)
                        {
                            Dictionary<string, string>.KeyCollection tmpKeys = cMenuConfigReader.DataSourcesToRegion[m_RegionsToUpdate[iKeyItem]].Keys;
                            foreach (string KeyItem in tmpKeys)
                            {
                                _TabPageRenderer.UpdateRegion(KeyItem);
                            }
                        }
                        m_RegionsToUpdate.Remove(iKeyItem);
                    }
                }
            }
            catch (Exception Ex)
            {               
                //Messagelogging.AppendMessage("Unable to update GUI!!", Ex, false, EMessageTypes.Error);
            }
        }

        void _ConfigMenuReader_UpdatedDataSource(object sender, DataSource e)
        {
            try
            {
                if (m_UpdatedDataSourceRunning == false)
                {
                    m_UpdatedDataSourceRunning = true;
                    if (m_RegionsToUpdate != null && m_RegionsToUpdate.ContainsValue(e.Name) == false)
                        m_RegionsToUpdate.Add(m_RegionsToUpdate.Count, e.Name);

                    m_UpdatedDataSourceRunning = false;
                }
            }
            catch (Exception ex)
            {
                CMessagelogging.AppendMessage("Unable to add updated DataSource to List!", ex, false, EMessageTypes.Error);
            }
        }

        void GUI_HeartBeat(object sender, EventArgs e)
        {
            try
            {
                TellCurrentHandle();
            }
            catch (Exception Ex)
            {
                CMessagelogging.AppendMessage("Unable to send Heartbeat!", Ex, EMessageTypes.Error);
            }
        }

        void InitGUIElementsForEvents()
        {
            try
            {
                cMenuConfigReader.GUIActionElements.Add(img_UserPicture.Name, img_UserPicture);
                cMenuConfigReader.GUIActionElements.Add(lbl_UserName.Name, lbl_UserName);
                cMenuConfigReader.GUIActionElements.Add(lbl_AppName.Name, lbl_AppName);
                cMenuConfigReader.GUIActionElements.Add(img_SearchPicture.Name, img_SearchPicture);
                cMenuConfigReader.GUIActionElements.Add(lbl_Search.Name, lbl_Search);
                cMenuConfigReader.GUIActionElements.Add(txt_ProgramSearchbox.Name, txt_ProgramSearchbox);
            }
            catch (Exception ex)
            {
                CMessagelogging.AppendMessage("Unable to Initialize GUI Elements!", ex, false, EMessageTypes.Error);
            }
        }
        
        #endregion

        #region DialogElement Events

        #region Renderer

        void _TabPageRenderer_SelectionChanged(object Sender, cStartmenuItem Item)
        {
            try
            {
                if (Item != null)
                {
                    if (Item.ItemType == eItemType.Link || Item.ItemType == eItemType.URL)
                    {
                        //Hide Startmenu
                        //HideStartMenu();
                        //Execute Link
                        switch (Item.ExecutionType)
                        {
                            case eLinkExecutionTypes.Program:
                                WMSSoft.Lib.Shell.ShellAPI.ShellExecute(0, "open", Item.LinkFilename, Item.Arguments, "", 5);
                                break;
                            case eLinkExecutionTypes.Code:
                                Execute_Procedure(Item.ExecutingProcedure);
                                break;
                        }                        
                    }
                }
            }
            catch (Exception ex)
            {
                CMessagelogging.AppendMessage("The selected link can't be run!", ex, true, EMessageTypes.Error);
            }
        }

        #endregion

        /// <summary>
        /// Process Raised Events configured in content.xml
        /// </summary>
        /// <param name="ObjectName">Source - Object for this Event</param>
        /// <param name="EventName">EventName</param>
        /// <param name="Value">Value for this event</param>
        private void ProcessEvent(string ObjectName, string EventName, Object Value)
        {
            try
            {
                if (cMenuConfigReader.EventSourceToActionName.ContainsKey(ObjectName) == true)
                {
                    string sActName = cMenuConfigReader.EventSourceToActionName[ObjectName];
                    bool bCanRunFunction = true;
                    if (cMenuConfigReader.Actions.ContainsKey(sActName) == true)
                    {
                        if (cMenuConfigReader.Actions[sActName].Triggers.ContainsKey(EventName) == true)
                        {
                            Dictionary<string, object> oFunctionParameters = new Dictionary<string, object>();
                            //Add Configuration Object to FunctionParameters
                            //oFunctionParameters.Add("WinKStart_Config", cMenuConfigReader);
                            oFunctionParameters.Add("Function_Config", cMenuConfigReader.FunctionsReader.Item[cMenuConfigReader.Actions[sActName].Function]);
                            //Add All source Elements to the Functions - DataParameter                            
                            foreach (SourceElement SourceElement in cMenuConfigReader.Actions[sActName].SourceElements)
                            {
                                if (cMenuConfigReader.GUIActionElements.ContainsKey(SourceElement.Element) == true)
                                {
                                    object oValue = null;
                                    try
                                    {
                                        _PropertyInfo prop = cMenuConfigReader.GUIActionElements[SourceElement.Element].GetType().GetProperty(SourceElement.Property);
                                        oValue = (object)prop.GetValue(cMenuConfigReader.GUIActionElements[SourceElement.Element], null);
                                    }
                                    catch (Exception Ex2)
                                    {
                                        CMessagelogging.AppendMessage("Source - Element (Property) doesn't exist or can't read!", Ex2, true, EMessageTypes.Information);
                                    }

                                    if (EventName.ToUpper() == "TEXTCHANGED")
                                    {
                                        //TODO: rewrite code to process configured action - events
                                        //if (((string)oValue).Length >= cMenuConfigReader.Actions[sActName].Triggers[EventName].DataLength)
                                        //    bCanRunFunction = true;
                                        //else
                                        //    bCanRunFunction = false;
                                        
                                    } 
                                    //Add SourceElement to FunctionParameters
                                    if (oFunctionParameters.ContainsKey(SourceElement.Property) == false)
                                        oFunctionParameters.Add(SourceElement.Property, oValue);
                                }
                            }
                                
                            //Run Function
                            if (cMenuConfigReader.FunctionsReader.ItemInstances.ContainsKey(cMenuConfigReader.Actions[sActName].Function) == true && bCanRunFunction == true)
                                cMenuConfigReader.FunctionsReader.ItemInstances[cMenuConfigReader.Actions[sActName].Function].Run(oFunctionParameters);
                            
                        }

                    }
                }
            }
            catch (Exception Ex)
            {
                CMessagelogging.AppendMessage("Can't process Event from " + ObjectName + " with an Event " + EventName, Ex,true, EMessageTypes.Information);
            }

        }

        /// <summary>
        /// Executes the in menux.xml in attribute ExecutionProcedure written procedure name
        /// </summary>
        /// <param name="Procedure"></param>
        void Execute_Procedure(eExecutionProcedure Procedure)
        {
            try
            {
                switch (Procedure)
                {
                    case eExecutionProcedure.lock_workstation:
                        WMSSoft.Lib.Shell.ShellAPI.LockWorkStation();
                        break;
                    case eExecutionProcedure.system_logout:
                        WMSSoft.Lib.Shell.ShellAPI.ExitWindowsEx(0, 0);
                        break;
                    case eExecutionProcedure.energy_save_mode:
                        System.Windows.Forms.Application.SetSuspendState(System.Windows.Forms.PowerState.Suspend, true, false);
                        break;
                    case eExecutionProcedure.hibernate_mode:
                        System.Windows.Forms.Application.SetSuspendState(System.Windows.Forms.PowerState.Hibernate, true, false);
                        break;
                    case eExecutionProcedure.winkstart_settings:
                        WMSSoft.WinKStart.ViewModel.CSettingsViewModel tmpViewModel = new ViewModel.CSettingsViewModel();
                        Settings tmpDialog = new Settings();
                        tmpDialog.DataContext = tmpViewModel;
                        tmpDialog.ViewModel = tmpViewModel;
                        tmpDialog.Show();
                        break;
                    case eExecutionProcedure.winkstart_about:
                        break;
                    case eExecutionProcedure.winkstart_close:
                        //implements code to
                        //  - unload all datasources
                        //  - unload websearch engine
                        //  - close window
                        m_GUI_Heartbeat.IsEnabled = false;
                        if (cMenuConfigReader.DataSources != null)
                        {
                            if (cMenuConfigReader.DataSources.Unload() == true)
                            {
                                //now we can stop next step websearchengines                                
                                //now we can close WinKStart
                                if (_iCloseRaiseCounter == 0)
                                {
                                    _iCloseRaiseCounter += 1;
                                    Close();
                                    
                                }
                            }
                        }                        
                        break;
                }
            }
            catch (Exception Ex)
            {
                throw new Exception("Unable to run Procedure '" + Procedure.ToString() + "'!");
            }
        }

#endregion        

        void m_WebSearchResultUpdate_Tick(object sender, EventArgs e)
        {
            try {
                
                m_WebSearchResultUpdate.Stop();

                //m_SearchResultRenderer.RenderGroupItems((cStartmenuItem)_ConfigMenuReader.RootSearchResult);
            }
            catch (Exception Ex)
            {
                CMessagelogging.AppendMessage("Can't apply Startmenu search Items!", Ex, true, EMessageTypes.Error);
            }
        }

        private void Window_KeyUp(object sender, KeyEventArgs e)
        {
            try
            {
                if (e.Key == Key.Escape) // && tbpLayerContainer.SelectedIndex == (int)ActiveTabItems.Search)
                {
                    ////Close searchresult frame
                    //tbpLayerContainer.SelectedIndex = _ActiveTabIndex;
                    ////SetActiveTab(_ActiveTabIndex);
                }
                else if (e.Key == Key.Right)
                {
                    _TabPageRenderer.SelectNextRegion();
                }
                else if (e.Key == Key.Left)
                {
                    _TabPageRenderer.SelectPreviousRegion();
                }
                else if (e.Key == Key.Up)
                {
                    //e.Handled = true;
                }
                else if (e.Key == Key.Down)
                {
                    //e.Handled = true;
                }
            }
            catch (Exception Ex)
            {
                CMessagelogging.AppendMessage("Can't Keyboard Event!", Ex, true, EMessageTypes.Error);
            }
        }

        private void txt_ProgramSearchbox_GotFocus(object sender, RoutedEventArgs e)
        {
            txt_ProgramSearchbox.BorderBrush = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
        }

        private IntPtr HandleMsg(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            return IntPtr.Zero;
        }

        private void frmWinKStartMain_Loaded(object sender, RoutedEventArgs e)
        {
            m_GUI_Heartbeat.IsEnabled = true;
            //HwndSource source = (HwndSource)HwndSource.FromVisual(this);
            //if (source != null)
            //    source.AddHook(HandleMsg);
            //IntPtr windowHandle = new WindowInteropHelper(Application.Current.MainWindow).Handle;
            //InitWinKStartCaller(windowHandle);
            this.Visibility = System.Windows.Visibility.Hidden;
        }

        private void frmWinKStartMain_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            CMessagelogging.AppendMessage("Start Shutdown WinKStart", EMessageTypes.Information);
            //CloseWinKStartCaller();
            CloseStartButton();

            CMessagelogging.AppendMessage("Shutdown WinKStart done", EMessageTypes.Information);
            //Close MessageLogging
            CMessagelogging.CloseLogging();
        }

        private void frmWinKStartMain_Deactivated(object sender, EventArgs e)
        {
            CMessagelogging.AppendMessage("WinKStart - StartMenu deactivated", EMessageTypes.Debug);
            //HideStartMenu();
            this.Visibility = System.Windows.Visibility.Hidden;
            WMSSoft.Lib.Shell.ShellAPI.SendMessage(GetStartButtonManagementHandle(), WMSSoft.Lib.Shell.ShellAPI.WM_ACTION_WINKSTART_NOTIFY_HIDDEN, IntPtr.Zero, IntPtr.Zero);
        }

        private void frmWinKStartMain_Activated(object sender, EventArgs e)
        {
            CMessagelogging.AppendMessage("WinKStart - StartMenu activated", EMessageTypes.Debug);
            this.Activate();
            this.Focus();
        }

    }
}